﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using Styx.CommonBot;
using Styx.Helpers;
using Styx.WoWInternals.WoWObjects;

namespace Portal.Helpers
{
    class Lua
    {
        private static readonly Dictionary<string, string> LocalizedSpellNames = new Dictionary<string, string>();

        public static string RealLuaEscape(string luastring)
        {
            var bytes = Encoding.UTF8.GetBytes(luastring);
            return bytes.Aggregate(String.Empty, (current, b) => current + ("\\" + b));
        }

        public static string LocalizeSpellName(string name)
        {
            if (LocalizedSpellNames.ContainsKey(name))
                return LocalizedSpellNames[name];

            string loc;

            int id = 0;
            try
            {
                id = SpellManager.Spells[name].Id;
            }
            catch
            {
                return name;
            }

            try
            {
                loc = Styx.WoWInternals.Lua.GetReturnValues("return select(1, GetSpellInfo(" + id + "))")[0];
            }
            catch
            {
                Log.Fail("Lua failed in LocalizeSpellName");
                return name;
            }

            LocalizedSpellNames[name] = loc;
            Log.Debug("Localized spell: '" + name + "' is '" + loc + "'.");
            return loc;
        }

        public static int PlayerCountBuff(string name)
        {
            name = LocalizeSpellName(name);
            try
            {
                var lua = String.Format("local x=select(4, UnitBuff('player', \"{0}\")); if x==nil then return 0 else return x end", RealLuaEscape(name));
                var t = Int32.Parse(Styx.WoWInternals.Lua.GetReturnValues(lua)[0]);
                return t;
            }
            catch
            {
                Log.Fail("Lua failed in PlayerCountBuff");
                return 0;
            }
        }
        // UnitSpellHaste("name")

        public static float GetSpellHaste()
        {
            try
            {
                //Styx.WoWInternals.Lua.GetReturnValues("return UnitSpellHaste('player')");
                return Styx.WoWInternals.Lua.GetReturnVal<float>("return GetCombatRating(CR_HASTE_SPELL)", 0);
            }
            catch
            {
                Log.Fail("Lua failed in PlayerCountBuff");
                return 0;
            }
        }

        #region Mouseover

        public static string MouseOverUnitName()
        {
            return Styx.WoWInternals.Lua.GetReturnValues("return UnitName('mouseover')")[0];
        }

        /// <summary>
        /// Returns GUID in Hex value - not the same as the HB GUID value (ulong)
        /// </summary>
        /// <returns>0 if no mouseover GUID</returns>
        public static string MouseOverUnitGuid()
        {
            return Styx.WoWInternals.Lua.GetReturnValues("if UnitGUID('mouseover')~=nil then return UnitGUID('mouseover') else return 0 end")[0] ?? "0";

        }

        #endregion

        #region Spell Charges
        public static int GetSpellCurrentCharges(int spellId)
        {
            try
            {
                // currentCharges, maxCharges, timeLastCast, cooldownDuration = GetSpellCharges(spellId or spellName)
                return Int32.Parse(Styx.WoWInternals.Lua.GetReturnValues("return GetSpellCharges(" + spellId + ")")[0]);
            }
            catch
            {
                Log.Fail("Lua failed in PlayerCountBuff");
                return 0;
            }
        }

        /// <summary>
        /// Returns the time remaining until the next charge of spell is available.
        /// </summary>
        /// <param name="spellId">Spell Id</param>
        /// <param name="rechargeTime">The recharge time of the spell</param>
        /// <returns>returns 0 if not on CD</returns>
        public static double GetSpellRechargeTime(int spellId, int rechargeTime)
        {
            try
            {
                // currentCharges, maxCharges, timeLastCast, cooldownDuration = GetSpellCharges(spellId or spellName)
                double val = Double.Parse(Styx.WoWInternals.Lua.GetReturnValues("local x=select(3, GetSpellCharges(" + spellId + ")); if x==nil then return 999 else return GetTime()-x end")[0]);

                if (val > 0)
                {
                    return (rechargeTime - val);
                }
                else
                {
                    return 0;
                }
            }
            catch
            {
                Log.Fail("Lua failed in PlayerCountBuff");
                return 999; 
            }
        }
        #endregion
    }
}
